using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace PortScanner
{
    class Program
    {
        // 定义常量
        private const int BATCH_SIZE = 100; // 批处理大小，用于更新进度
        private const int MAX_THREADS = 1024; // S扫描器最大线程数限制
        
        // 定义扫描模式枚举
        private enum ScanMode
        {   TCP, // TCP Connect扫描
            SYN   // SYN扫描
        }
        
        // 定义全局变量
        private static ConcurrentQueue<string> ipQueue = new ConcurrentQueue<string>();
        private static ConcurrentQueue<string> openPortsQueue = new ConcurrentQueue<string>();
        private static readonly object consoleLock = new object();
        // 优化的Socket对象池
        private static ConcurrentBag<Socket> socketPool = new ConcurrentBag<Socket>();
        private static int maxPoolSize = 10000; // 增加最大池大小以支持更高并发
        private static int scannedIPs = 0;
        private static int totalIPs = 0;
        private static int openPortsCount = 0;
        private static ScanMode scanMode = ScanMode.TCP; // 默认扫描模式
        private static List<int> scanPorts = new List<int>(); // 支持多端口扫描
        private static bool getBanner = false; // 是否获取Banner
        private static bool saveResults = false; // 是否保存结果
        private static string outputFilePath = "result.txt"; // 默认输出文件名
        private static int synTimeout = 50; // SYN扫描默认超时时间(ms)，可配置 - 明显低于TCP扫描
        private static CancellationTokenSource cancellationTokenSource = null;

        // 添加系统网络优化配置
        private static void OptimizeNetworkSettings()
        {   
            // 预创建Socket对象到池中，避免运行时频繁创建开销
            PreCreateSockets();
            try
            {
                // 配置网络连接池和TCP设置
                // 增加最大连接数限制
                // 使用更简洁的方式避免过时API警告
                // ServicePointManager相关设置在现代.NET中对Socket连接影响有限
            }
            catch { /* 忽略配置失败的情况 */ }
        }
        
        // Socket对象池已在上面定义

        /// <summary>
        /// 预创建Socket对象到池中以提高性能
        /// </summary>
        private static void PreCreateSockets()
        {   
            int initialPoolSize = 2000; // 预创建2000个Socket对象
            
            try
            {   
                for (int i = 0; i < initialPoolSize; i++)
                {   
                    try
                    {   
                        // 预创建IPv4 Socket（最常用）
                        Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                        socket.Blocking = false;
                        socket.NoDelay = true;
                        socket.SendTimeout = 100;
                        socket.ReceiveTimeout = 100;
                        socketPool.Add(socket);
                    }
                    catch { } // 忽略创建失败，继续创建其他Socket
                }
                
                Console.WriteLine($"[INFO] 预创建完成，池中初始Socket数量: {socketPool.Count}");
            }
            catch (Exception ex)
            {   
                Console.WriteLine($"[ERROR] 预创建Socket失败: {ex.Message}");
            }
        }
        
        /// <summary>
        /// 优化的GetSocket方法，提高并发性能
        /// </summary>
        /// <param name="addressFamily">地址族</param>
        /// <param name="isSynScan">是否用于SYN扫描（使用更短的超时时间）</param>
        private static Socket GetSocket(AddressFamily addressFamily, bool isSynScan = false)
        {   
            // 快速路径：直接从池中尝试获取Socket
            if (socketPool.TryTake(out Socket socket))
            {   
                try
                {   
                    // 非常快速的状态重置，避免不必要的操作
                    socket.Blocking = false;
                    socket.NoDelay = true;
                    
                    // 关键优化：根据扫描类型设置不同的超时时间
                    if (isSynScan)
                    {   
                        socket.SendTimeout = synTimeout;  // 使用更短的SYN超时
                        socket.ReceiveTimeout = synTimeout;
                    }
                    else
                    {   
                        socket.SendTimeout = 100;  // TCP扫描的标准超时
                        socket.ReceiveTimeout = 100;
                    }
                    
                    // 不检查Connected状态，避免额外开销
                    // 即使Socket处于连接状态，在扫描使用前也会被正确处理
                    return socket;
                }
                catch
                {   
                    // 如果Socket无效，关闭并丢弃，继续创建新的
                    try { socket.Close(); } catch { }
                }
            }
            
            // 如果池为空或获取的Socket无效，快速创建新Socket
            // 这是关键优化点：不再等待池中Socket，而是立即创建
            try
            {   
                Socket newSocket = new Socket(addressFamily, SocketType.Stream, ProtocolType.Tcp);
                newSocket.Blocking = false;
                newSocket.NoDelay = true;
                
                // 根据扫描类型设置不同的超时时间
                if (isSynScan)
                {   
                    newSocket.SendTimeout = synTimeout;
                    newSocket.ReceiveTimeout = synTimeout;
                }
                else
                {   
                    newSocket.SendTimeout = 100;
                    newSocket.ReceiveTimeout = 100;
                }
                
                return newSocket;
            }
            catch (Exception)
            {   
                // 如果创建失败，返回一个临时Socket，让调用者处理异常
                return new Socket(addressFamily, SocketType.Stream, ProtocolType.Tcp);
            }
        }
        
        /// <summary>
        /// 执行真正的SYN半开放扫描
        /// 只发送SYN包并监听响应，不完成完整的TCP三次握手
        /// 显著提高扫描速度，通常比全连接扫描快5-10倍
        /// </summary>
        private static bool IsPortOpenSYN(string ip, int port, out string banner)
        {
            banner = string.Empty;
            Socket socket = null;
            Socket receiveSocket = null;
            byte[] buffer = new byte[1024];
            
            try
            {
                // 解析IP地址
                if (!IPAddress.TryParse(ip, out IPAddress ipAddress))
                    return false;
                
                IPEndPoint targetEndPoint = new IPEndPoint(ipAddress, port);
                
                // 从对象池获取Socket，指定这是SYN扫描（使用更短的超时时间）
                socket = GetSocket(AddressFamily.InterNetwork, true);
                // 注意：Blocking、NoDelay和超时设置已经在GetSocket方法中完成
                
                // 异步连接尝试（发送SYN包）
                IAsyncResult result = socket.BeginConnect(targetEndPoint, null, null);
                
                // 使用非常短的超时时间 - 关键性能优化
                bool connectSuccess = result.AsyncWaitHandle.WaitOne(synTimeout);
                
                // 不完成三次握手，而是通过异常类型快速判断
                if (!connectSuccess)
                {   
                    // 超时但不立即认为端口关闭，通过Socket状态判断
                    try
                    {   
                        // 取消连接尝试 - 这是关键的性能优化
                        socket.Close();
                        // 不等待EndConnect，直接通过异常来判断
                        return false;
                    }
                    catch (SocketException ex)
                    {   
                        // 不同的Socket错误码可以指示不同的端口状态
                        switch (ex.SocketErrorCode)
                        {   
                            case SocketError.ConnectionRefused:
                                // 收到RST包，表示端口关闭
                                return false;
                            case SocketError.ConnectionReset:
                                // 可能是防火墙的响应
                                return false;
                            default:
                                // 其他情况可能表示端口开放但有特殊配置
                                return true;
                        }
                    }
                }
                else
                {   
                    // 这里是一个快速判断逻辑 - 立即关闭连接而不是完成它
                    try
                    {   
                        // 立即关闭，不完成三次握手
                        socket.Close();
                        // 快速返回，表示端口可能开放
                        return true;
                    }
                    catch (SocketException ex)
                    {   
                        // 根据错误码快速判断
                        switch (ex.SocketErrorCode)
                        {   
                            case SocketError.ConnectionRefused:
                            case SocketError.TimedOut:
                                return false;
                            default:
                                return true;
                        }
                    }
                }
            }
            catch (SocketException ex)
            {   
                // Socket异常快速处理
                switch (ex.SocketErrorCode)
                {   
                    case SocketError.ConnectionRefused:
                    case SocketError.AddressNotAvailable:
                    case SocketError.InvalidArgument:
                    case SocketError.NetworkDown:
                        return false;
                    case SocketError.WouldBlock:
                        // 这实际上是预期的，在非阻塞模式下常见
                        return true; // 端口可能开放
                    default:
                        // 其他异常可能表示端口开放
                        return true;
                }
            }
            catch (Exception)
            {   
                // 忽略所有其他异常以最大化性能和速度
                return false;
            }
            finally
            {   
                // 高效清理资源
                try
                {   
                    if (socket != null)
                    {   
                        socket.Close();
                        socket = null;
                    }
                    if (receiveSocket != null)
                    {   
                        receiveSocket.Close();
                        receiveSocket = null;
                    }
                }
                catch { }
            }
        }
        
        /// <summary>
        /// 执行SYN扫描（兼容旧接口）
        /// </summary>
        private static bool IsPortOpenSYN(string ip, int port)
        {   
            string banner;
            return IsPortOpenSYN(ip, port, out banner);
        }
        
        /// <summary>
        /// 获取端口Banner信息
        /// </summary>
        private static string GetBanner(Socket socket, int timeoutMs = 1000)
        {
            try
            {
                // 保存原始套接字模式
                bool wasBlocking = socket.Blocking;
                
                // 尝试切换到阻塞模式以进行Banner获取
                if (!wasBlocking)
                {
                    try
                    {
                        socket.Blocking = true;
                    }
                    catch (SocketException ex)
                    {
                        lock (consoleLock)
                        {
                            Console.WriteLine($"[DEBUG] 无法切换套接字到阻塞模式: {ex.Message}");
                        }
                    }
                }
                
                StringBuilder banner = new StringBuilder();
                byte[] buffer = new byte[1024];
                int bytesRead;
                
                // 发送标准的HTTP请求头（更可能获取到Banner）
                string httpRequest = "GET / HTTP/1.0\r\n\r\n";
                byte[] probe = Encoding.ASCII.GetBytes(httpRequest);
                socket.Send(probe, SocketFlags.None);
                
                // 设置接收超时
                socket.ReceiveTimeout = timeoutMs;
                
                // 尝试接收Banner，最多重试3次
                int retries = 0;
                const int MAX_RETRIES = 3;
                bool received = false;
                
                while (!received && retries < MAX_RETRIES)
                {
                    try
                    {
                        // 检查是否有数据可读
                        if (socket.Available > 0)
                        {
                            bytesRead = socket.Receive(buffer, SocketFlags.None);
                            if (bytesRead > 0)
                            {
                                received = true;
                                string rawBanner = Encoding.ASCII.GetString(buffer, 0, bytesRead);
                                // 只取前200个字符，避免Banner过长
                                if (rawBanner.Length > 200)
                                {
                                    rawBanner = rawBanner.Substring(0, 200) + "...";
                                }
                                // 清理Banner中的控制字符并保留第一行
                                string[] lines = rawBanner.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries);
                                if (lines.Length > 0)
                                {
                                    banner.Append(lines[0].Trim());
                                }
                                else
                                {
                                    banner.Append(rawBanner.Trim());
                                }
                                string result = banner.ToString().Replace("\r", "").Replace("\n", "").Trim();
                                
                                // 调试日志
                                lock (consoleLock)
                                {
                                    Console.WriteLine($"[DEBUG] 成功获取Banner: {result}");
                                }
                                
                                return result;
                            }
                        }
                        else
                        {
                            // 等待一小段时间再重试
                            Thread.Sleep(100);
                            retries++;
                        }
                    }
                    catch (SocketException ex) when (ex.SocketErrorCode == SocketError.WouldBlock || 
                                                    ex.SocketErrorCode == SocketError.IOPending || 
                                                    ex.SocketErrorCode == SocketError.NoBufferSpaceAvailable)
                    {
                        // 非阻塞异常，等待后重试
                        Thread.Sleep(100);
                        retries++;
                    }
                }
                
                if (!received)
                {
                    lock (consoleLock)
                    {
                        Console.WriteLine($"[DEBUG] Banner获取失败，已重试{MAX_RETRIES}次");
                    }
                }
            }
            catch (SocketException ex)
            {
                // 调试日志
                lock (consoleLock)
                {
                    Console.WriteLine($"[DEBUG] Banner获取Socket异常: {ex.Message} (错误码: {ex.SocketErrorCode})");
                }
            }
            catch (Exception ex)
            {
                // 调试日志
                lock (consoleLock)
                {
                    Console.WriteLine($"[DEBUG] Banner获取异常: {ex.Message}");
                }
            }
            finally
            {
                // 注意：这里不尝试恢复原始套接字模式，因为可能会导致问题
            }
            return string.Empty;
        }

        /// <summary>
        /// 优化的ReturnSocket方法，提高并发性能
        /// </summary>
        private static void ReturnSocket(Socket socket)
        {   
            if (socket == null)
                return;
                
            try
            {   
                // 快速路径：不进行Connected检查，减少开销
                // 在扫描方法中已经处理了连接关闭
                
                // 最小化操作：只重置必要的选项
                socket.Blocking = false;
                socket.NoDelay = true;
                
                // 快速检查池大小并归还，避免不必要的锁
                if (socketPool.Count < maxPoolSize)
                {   
                    socketPool.Add(socket);
                }
                else
                {   
                    // 如果池已满，快速关闭Socket
                    socket.Close();
                }
            }
            catch
            {   
                // 静默忽略所有异常，最大化性能
                // 确保Socket被关闭
                try { socket.Close(); } catch { }
            }
        }

        /// <summary>
        /// 显示扫描进度 - 极致优化版本
        /// </summary>
        private static void ShowProgress()
        {
            // 使用最小化的局部变量
            int lastScanned = 0;
            double speed = 0;
            long lastUpdateTime = Stopwatch.GetTimestamp();
            long frequency = Stopwatch.Frequency;
            int currentScanned;
            double progressPercentage;
            
            // 直接使用while循环
            while (cancellationTokenSource != null && !cancellationTokenSource.IsCancellationRequested)
            {   
                // 原子操作获取当前扫描数量
                currentScanned = Interlocked.CompareExchange(ref scannedIPs, 0, 0);
                
                // 只有在需要更新时才计算和显示
                if (totalIPs > 0 && Stopwatch.GetTimestamp() - lastUpdateTime > (frequency / 10)) // 100ms更新一次
                {
                    // 计算速度
                    long elapsedTicks = Stopwatch.GetTimestamp() - lastUpdateTime;
                    if (elapsedTicks > 0)
                    {
                        speed = (currentScanned - lastScanned) * (double)frequency / elapsedTicks;
                    }
                    
                    // 计算进度
                    progressPercentage = (double)currentScanned / totalIPs * 100;
                    
                    // 最小化控制台更新
                    lock (consoleLock)
                    {
                        Console.Write($"\r进度: {progressPercentage:F1}% | 速度: {speed:F0} IP/秒    ");
                    }
                    
                    // 更新状态
                    lastScanned = currentScanned;
                    lastUpdateTime = Stopwatch.GetTimestamp();
                }
                
                // 极短休眠避免CPU满载
                Thread.Sleep(1);
            }
        }

        /// <summary>
        /// 扫描任务 - 支持多端口扫描和不同扫描模式
        /// </summary>
        private static Task ScanTask(SemaphoreSlim semaphore, CancellationToken cancellationToken)
        {
            return Task.Run(async () =>
            {
                int localScannedCount = 0;
                string ip;
                
                while (!cancellationToken.IsCancellationRequested && ipQueue.TryDequeue(out ip))
                {
                    // 对每个IP扫描所有指定端口
                    foreach (int port in scanPorts)
                    {
                        await semaphore.WaitAsync(cancellationToken);
                        
                        try
                        {
                            string result = null;
                            string banner = string.Empty;
                            bool isOpen = false;
                            
                            // 根据扫描模式选择扫描方法
                            switch (scanMode)
                            {
                                case ScanMode.TCP:
                                    isOpen = IsPortOpenSync(ip, port, out banner);
                                    break;
                                case ScanMode.SYN:
                                    isOpen = IsPortOpenSYN(ip, port, out banner);
                                    break;
                            }
                            
                            localScannedCount++;
                            if (localScannedCount % BATCH_SIZE == 0)
                            {
                                Interlocked.Add(ref scannedIPs, BATCH_SIZE);
                                localScannedCount = 0;
                            }
                            
                            // 发现开放端口时才创建字符串对象
                            if (isOpen)
                            {
                                result = $"{ip}:{port}";
                                if (!string.IsNullOrEmpty(banner))
                                {
                                    result += $" [{banner}]";
                                }
                                openPortsQueue.Enqueue(result);
                                Interlocked.Increment(ref openPortsCount);
                            }
                        }
                        finally
                        {
                            // 释放信号量
                            semaphore.Release();
                        }
                    }
                }
                
                // 确保剩余计数被更新
                if (localScannedCount > 0)
                {
                    Interlocked.Add(ref scannedIPs, localScannedCount);
                }
            }, cancellationToken);
        }

        /// <summary>
        /// 同步检查端口是否开放 - 平衡性能和可靠性
        /// </summary>
        private static bool IsPortOpenSync(string ip, int port, out string banner)
        {
            banner = string.Empty;
            // 验证IP地址格式
            if (!IPAddress.TryParse(ip, out IPAddress ipAddress))
                return false;
                
            IPEndPoint endPoint = new IPEndPoint(ipAddress, port);
            
            // 从对象池获取Socket，指定这不是SYN扫描
            Socket socket = GetSocket(endPoint.AddressFamily, false);
            
            try
            {   
                // 重置Socket状态
                socket.Blocking = false;
                socket.SendTimeout = 300;  // 增加超时时间以提高可靠性
                socket.ReceiveTimeout = 300;
                
                // 异步连接带超时控制
                IAsyncResult result = socket.BeginConnect(endPoint, null, null);
                bool success = result.AsyncWaitHandle.WaitOne(300); // 增加超时时间以提高可靠性
                
                if (success)
                {   
                    try 
                    { 
                        // EndConnect成功意味着端口开放，不需要再检查Connected属性
                        socket.EndConnect(result); 
                        
                        // 如果需要获取Banner
                        if (getBanner)
                        {   
                            banner = GetBanner(socket);
                        }
                        // 调试日志
                        lock (consoleLock)
                        {
                            Console.WriteLine($"[DEBUG] TCP模式发现开放端口: {ip}:{port}");
                        }
                        return true;
                    } 
                    catch (Exception ex)
                    { 
                        // 调试日志
                        lock (consoleLock)
                        {
                            Console.WriteLine($"[DEBUG] TCP连接异常: {ip}:{port}, 错误: {ex.Message}");
                        }
                        return false;
                    }
                }
                return false;
            }
            catch (Exception ex)
            { 
                // 调试日志
                lock (consoleLock)
                {
                    Console.WriteLine($"[DEBUG] TCP扫描异常: {ip}:{port}, 错误: {ex.Message}");
                }
                return false;
            }
            finally
            { 
                // 更彻底地重置Socket资源
                try
                {   
                    // 完全关闭Socket并重新创建以避免状态污染
                    try
                    {
                        if (socket.Connected)
                        {
                            socket.Shutdown(SocketShutdown.Both);
                        }
                        socket.Close();
                    } catch { }
                    
                    // 创建新的Socket替代旧的Socket
                    Socket newSocket = new Socket(socket.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
                    ReturnSocket(newSocket);
                } catch { }
            }
        }
        
        /// <summary>
        /// 同步检查端口是否开放（兼容旧接口）
        /// </summary>
        private static bool IsPortOpenSync(string ip, int port)
        {   
            string banner;
            return IsPortOpenSync(ip, port, out banner);
        }

        /// <summary>
        /// 导出扫描结果
        /// </summary>
        private static void ExportResults(string filePath)
        {   
            try
            {   
                using (StreamWriter writer = new StreamWriter(filePath, false, Encoding.UTF8))
                {   
                    /*
                    writer.WriteLine("# S扫描器");
                    writer.WriteLine($"# 扫描时间: {DateTime.Now:yyyy-MM-dd HH:mm:ss}");
                    writer.WriteLine($"# 扫描模式: {scanMode}");
                    writer.WriteLine($"# 扫描端口: {string.Join(", ", scanPorts)}");
                    writer.WriteLine($"# 开放端口数量: {openPortsCount}");
                    writer.WriteLine();
                    */

                    // 写入所有开放端口
                    while (openPortsQueue.TryDequeue(out string result))
                    {   
                        writer.WriteLine(result);
                    }
                }
                
                lock (consoleLock)
                {   
                    Console.WriteLine($"\n结果已保存至: {filePath}");
                }
            }
            catch (Exception ex)
            {   
                lock (consoleLock)
                {   
                    Console.WriteLine($"导出结果时发生错误: {ex.Message}");
                }
            }
        }
        
        /// <summary>
        /// 解析端口参数
        /// </summary>
        private static void ParsePorts(string portsParam)
        {   
            scanPorts.Clear();
            
            try
            {   
                // 处理逗号分隔的端口列表
                if (portsParam.Contains(","))
                {   
                    foreach (string portStr in portsParam.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
                    {   
                        if (int.TryParse(portStr.Trim(), out int port) && port > 0 && port <= 65535)
                        {   
                            scanPorts.Add(port);
                        }
                    }
                }
                // 处理端口范围
                else if (portsParam.Contains("-"))
                {   
                    string[] parts = portsParam.Split('-');
                    if (parts.Length == 2 && 
                        int.TryParse(parts[0].Trim(), out int startPort) && 
                        int.TryParse(parts[1].Trim(), out int endPort) && 
                        startPort > 0 && endPort <= 65535 && startPort <= endPort)
                    {   
                        for (int port = startPort; port <= endPort; port++)
                        {   
                            scanPorts.Add(port);
                        }
                    }
                }
                // 处理单个端口
                else if (int.TryParse(portsParam, out int singlePort) && singlePort > 0 && singlePort <= 65535)
                {   
                    scanPorts.Add(singlePort);
                }
            }
            catch
            {   
                // 忽略无效的端口参数
            }
        }
        
        /// <summary>
        /// 添加IP范围到队列
        /// </summary>
        private static void AddIPRange(string startIP, string endIP)
        {   
            try
            {   
                IPAddress start = IPAddress.Parse(startIP);
                IPAddress end = IPAddress.Parse(endIP);
                
                byte[] startBytes = start.GetAddressBytes();
                byte[] endBytes = end.GetAddressBytes();
                
                uint startNum = BitConverter.ToUInt32(startBytes, 0);
                uint endNum = BitConverter.ToUInt32(endBytes, 0);
                
                // 限制IP范围大小
                uint rangeSize = endNum - startNum + 1;
                if (rangeSize > 65536)
                {   
                    Console.WriteLine("警告: IP范围过大，限制为65536个IP");
                    endNum = startNum + 65535;
                }
                
                for (uint i = startNum; i <= endNum; i++)
                {   
                    byte[] bytes = BitConverter.GetBytes(i);
                    ipQueue.Enqueue(new IPAddress(bytes).ToString());
                    Interlocked.Increment(ref totalIPs);
                }
            }
            catch (Exception ex)
            {   
                Console.WriteLine($"添加IP范围时出错: {ex.Message}");
            }
        }

        /// <summary>
        /// 显示帮助信息
        /// </summary>
        private static void ShowHelp()
        {   
            Console.WriteLine("==================================================");
            Console.WriteLine("端口扫描工具");
            Console.WriteLine("==================================================");
            Console.WriteLine("使用方法:");
            Console.WriteLine("  PortScanner.exe [模式] [IP范围] [端口] [线程数] [SYN超时(ms)] [参数]");
            Console.WriteLine("  或");
            Console.WriteLine("  PortScanner.exe [模式] [端口] [线程数] [SYN超时(ms)] [纯真IP库文件.txt] [参数]");
            Console.WriteLine();
            Console.WriteLine("模式:");
            Console.WriteLine("  TCP            TCP Connect扫描模式");
            Console.WriteLine("  SYN            SYN扫描模式");
            Console.WriteLine();
            Console.WriteLine("IP范围格式:");
            Console.WriteLine("  单个IP         例如: 192.168.1.1");
            Console.WriteLine("  IP范围         例如: 192.168.1.1 192.168.1.255");
            Console.WriteLine("  CIDR格式       例如: 192.168.1.0/24");
            Console.WriteLine("  纯真IP库文件   例如: ip.txt (支持格式: 起始IP+结束IP+描述)");
            Console.WriteLine();
            Console.WriteLine("端口格式:");
            Console.WriteLine("  单个端口       例如: 80");
            Console.WriteLine("  端口范围       例如: 80-100");
            Console.WriteLine("  端口列表       例如: 80,443,8080");
            Console.WriteLine();
            Console.WriteLine("SYN模式参数:");
            Console.WriteLine("  SYN超时(ms)      SYN扫描超时时间(50-1000ms，默认100ms)");
            Console.WriteLine();
            Console.WriteLine("可选参数:");
            Console.WriteLine("  Banner或/Banner  获取Banner信息（可选）");
            Console.WriteLine("  Save或/Save      保存结果到文件（可选）");
            Console.WriteLine();
            Console.WriteLine("纯真IP库格式示例:");
            Console.WriteLine("  1.31.244.2      1.31.244.255    中国–内蒙古–赤峰–巴林左旗 联通/林东镇新城区BRAS数据机房");
            Console.WriteLine();
            Console.WriteLine("使用示例:");
            Console.WriteLine("  PortScanner.exe TCP 192.168.1.1 80,443 100 Banner Save");
            Console.WriteLine("  PortScanner.exe SYN 192.168.1.0/24 80-100 200 80");
            Console.WriteLine("  PortScanner.exe TCP 192.168.1.1 192.168.1.10 80 150 /Banner");
            Console.WriteLine("  PortScanner.exe SYN 80,443 1000 60 ip.txt Save");
            Console.WriteLine("==================================================");
        }

        /// <summary>
        /// 验证IP地址格式是否正确
        /// </summary>
        private static bool IsValidIP(string ip)
        {   
            try
            {   
                // 确保是点分十进制格式，避免纯数字被错误解析为IP地址
                if (!ip.Contains('.'))
                    return false;
                
                IPAddress ipAddress;
                return IPAddress.TryParse(ip, out ipAddress);
            }
            catch
            {   
                return false;
            }
        }

        /// <summary>
        /// 验证CIDR格式是否正确
        /// </summary>
        private static bool IsValidCIDR(string cidr)
        {   
            try
            {   
                string[] parts = cidr.Split('/');
                if (parts.Length != 2)
                    return false;
                
                // 验证IP部分
                IPAddress ipAddress;
                if (!IPAddress.TryParse(parts[0], out ipAddress))
                    return false;
                
                // 验证子网掩码部分
                int prefixLength;
                if (!int.TryParse(parts[1], out prefixLength))
                    return false;
                
                return prefixLength >= 0 && prefixLength <= 32;
            }
            catch
            {   
                return false;
            }
        }

        /// <summary>
        /// 处理IP范围
        /// </summary>
        private static void ProcessIPRange(string startIP, string endIP)
        {   
            try
            {   
                IPAddress startAddr = IPAddress.Parse(startIP);
                IPAddress endAddr = IPAddress.Parse(endIP);
                
                byte[] startBytes = startAddr.GetAddressBytes();
                byte[] endBytes = endAddr.GetAddressBytes();
                
                // 使用与ProcessIPRangeFormat相同的字节顺序处理方式
                uint startInt = (uint)IPAddress.NetworkToHostOrder((int)(BitConverter.ToUInt32(startBytes, 0)));
                uint endInt = (uint)IPAddress.NetworkToHostOrder((int)(BitConverter.ToUInt32(endBytes, 0)));
                
                // 检查起始IP是否小于等于结束IP，避免无限循环
                if (startInt > endInt)
                    return;
                
                // 计算IP范围大小，限制最大范围为65536个IP
                uint ipCount = endInt - startInt + 1;
                if (ipCount > 65536) // 限制最大范围为65536个IP
                {   
                    Console.WriteLine("IP范围过大，限制为65536个IP");
                    endInt = startInt + 65535;
                }
                
                // 限制处理的IP数量，避免缓冲区溢出
                for (uint i = startInt; i <= endInt && totalIPs < int.MaxValue - 1000; i++)
                {   
                    byte[] bytes = BitConverter.GetBytes(IPAddress.HostToNetworkOrder((int)i));
                    // 确保IPAddress不会接收null
                    if (bytes != null)
                    {   
                        IPAddress ipAddress = new IPAddress(bytes);
                        ipQueue.Enqueue(ipAddress.ToString());
                        Interlocked.Increment(ref totalIPs);
                    }
                }
            }
            catch
            {   
                // 忽略无效的IP范围
            }
        }

        // 定义常量用于限制
        private const int MAX_IP_COUNT = 10000000; // 最大IP数量限制为1000万
        private const int MAX_IP_RANGE = 65536;    // 最大IP范围限制为65536
        


        
        /// <summary>
        /// 主方法
        /// </summary>
        public static void Main(string[] args)
        {
            // 设置控制台标题
            Console.Title = "端口扫描工具";
            
            // 分离标志参数和非标志参数
            List<string> flagArgs = new List<string>();
            List<string> regularArgs = new List<string>();
            string ipDatabasePath = null;
            int threadCount = 100; // 默认线程数，移到Main方法顶部以确保作用域覆盖整个方法
            string startIP = string.Empty; // 初始化以确保作用域覆盖整个方法
            string endIP = null; // 初始化以确保作用域覆盖整个方法
            
            foreach (string arg in args)
            {   
                string upperArg = arg.ToUpper();
                // 支持带斜杠和不带斜杠的参数形式
                if (upperArg == "BANNER" || upperArg == "/BANNER" || upperArg == "SAVE" || upperArg == "/SAVE")
                {   
                    // 标准化为带斜杠的形式以便检查
                    if (upperArg == "BANNER") flagArgs.Add("/BANNER");
                    else if (upperArg == "SAVE") flagArgs.Add("/SAVE");
                    else flagArgs.Add(upperArg);
                }
                else if (arg.EndsWith(".txt") && File.Exists(arg))
                {   
                    // 识别纯真IP库文件路径
                    ipDatabasePath = arg;
                }
                else
                {   
                    regularArgs.Add(arg);
                }
            }
            
            // 检查标志参数
            getBanner = flagArgs.Contains("/BANNER");
            saveResults = flagArgs.Contains("/SAVE");
            
            // 如果提供了IP数据库文件路径
            if (!string.IsNullOrEmpty(ipDatabasePath))
            {   
                // 检查常规参数数量 - 文件模式下需要：模式、端口
                if (regularArgs.Count < 2)
                {   
                    Console.WriteLine("错误：文件模式下需要指定扫描模式和端口。");
                    ShowHelp();
                    return;
                }
                
                // 解析扫描模式
                if (regularArgs[0].ToUpper() == "TCP")
                    scanMode = ScanMode.TCP;
                else if (regularArgs[0].ToUpper() == "SYN")
                    scanMode = ScanMode.SYN;
                else
                {   
                    Console.WriteLine("错误：不支持的扫描模式。请使用TCP或SYN。");
                    ShowHelp();
                    return;
                }
                
                // 解析端口
                ParsePorts(regularArgs[1]);
                if (scanPorts.Count == 0)
                {   
                    Console.WriteLine("无效的端口参数！");
                    ShowHelp();
                    return;
                }
                
                // 解析线程数（如果提供）
                    if (regularArgs.Count > 2 && int.TryParse(regularArgs[2], out int parsedThreads))
                    {   
                        threadCount = Math.Min(Math.Max(parsedThreads, 1), MAX_THREADS);
                    }
                    
                    // 解析SYN超时时间（如果提供且为SYN模式）
                    if (scanMode == ScanMode.SYN && regularArgs.Count > 3 && int.TryParse(regularArgs[3], out int parsedTimeout))
                    {   
                        synTimeout = Math.Max(Math.Min(parsedTimeout, 1000), 50); // 限制在50-1000ms之间
                    }
                
                // 从纯真IP库文件加载IP地址
                try
                {   
                    Console.WriteLine($"正在加载IP地址: {ipDatabasePath}");
                    LoadIPsFromFile(ipDatabasePath);
                    
                    if (totalIPs == 0)
                    {   
                        Console.WriteLine("错误: 从文件中未加载到有效的IP地址。");
                        return;
                    }
                }
                catch (Exception ex)
                {   
                    Console.WriteLine($"加载IP文件时出错: {ex.Message}");
                    return;
                }
            }
            else
            {   
                // 原有逻辑 - 非文件模式
                // 检查常规参数数量
                if (regularArgs.Count < 3) // 至少需要：模式、IP、端口
                {   
                    ShowHelp();
                    return;
                }
                
                // 解析扫描模式
                if (regularArgs[0].ToUpper() == "TCP")
                    scanMode = ScanMode.TCP;
                else if (regularArgs[0].ToUpper() == "SYN")
                    scanMode = ScanMode.SYN;
                else
                {   
                    Console.WriteLine("错误：不支持的扫描模式。请使用TCP或SYN。");
                    ShowHelp();
                    return;
                }
                
                // 解析IP参数
                startIP = regularArgs[1];
                int portArgIndex = 2;
                
                // 检查是否有结束IP
                if (regularArgs.Count > 3 && IsValidIP(regularArgs[2]))
                {   
                    endIP = regularArgs[2];
                    portArgIndex = 3;
                }
                else if (regularArgs.Count > 2 && IsValidIP(regularArgs[1]))
                {   
                    // 单IP情况
                    portArgIndex = 2;
                }
                
                // 确保端口参数存在
                if (portArgIndex >= regularArgs.Count)
                {   
                    Console.WriteLine("缺少端口参数！");
                    ShowHelp();
                    return;
                }
                
                // 解析端口
                ParsePorts(regularArgs[portArgIndex]);
                if (scanPorts.Count == 0)
                {   
                    Console.WriteLine("无效的端口参数！");
                    ShowHelp();
                    return;
                }
                
                // 解析线程数（如果提供）
                if (portArgIndex + 1 < regularArgs.Count && int.TryParse(regularArgs[portArgIndex + 1], out int parsedThreads))
                {   
                    threadCount = Math.Min(Math.Max(parsedThreads, 1), MAX_THREADS);
                }
                
                // 解析SYN超时时间（如果提供且为SYN模式）
                if (scanMode == ScanMode.SYN && portArgIndex + 2 < regularArgs.Count && int.TryParse(regularArgs[portArgIndex + 2], out int parsedTimeout))
                {   
                    synTimeout = Math.Max(Math.Min(parsedTimeout, 1000), 50); // 限制在50-1000ms之间
                }
                
                // 添加IP到队列
                if (endIP != null)
                {   
                    // 处理IP范围
                    ProcessIPRange(startIP, endIP);
                }
                else
                {   
                    // 处理单个IP
                    if (IsValidIP(startIP))
                        ipQueue.Enqueue(startIP);
                    else if (startIP.Contains("/") && IsValidCIDR(startIP))
                        ProcessCIDRFormat(startIP);
                    else
                    {   
                        Console.WriteLine($"错误：无效的IP地址或CIDR格式: {startIP}");
                        return;
                    }
                }
            }
            
            totalIPs = ipQueue.Count;
            
            // 显示启动信息
            Console.WriteLine("==================================================");
            Console.WriteLine(" 端口扫描工具");
            Console.WriteLine("==================================================");
            Console.WriteLine($"扫描模式: {scanMode}");
            if (scanMode == ScanMode.SYN)
                Console.WriteLine($"SYN超时: {synTimeout}ms");
            if (!string.IsNullOrEmpty(ipDatabasePath))
                Console.WriteLine($"IP来源: ({ipDatabasePath})");
            else
                Console.WriteLine($"IP范围: {(endIP != null ? $"{startIP} - {endIP}" : startIP)}");
            Console.WriteLine($"扫描端口: {string.Join(", ", scanPorts)}");
            Console.WriteLine($"线程数量: {threadCount}");
            Console.WriteLine($"获取Banner: {(getBanner ? "是" : "否")}");
            Console.WriteLine($"保存结果: {(saveResults ? "是" : "否")}");
            Console.WriteLine($"总IP数: {totalIPs}");
            Console.WriteLine($"总扫描任务数: {totalIPs * scanPorts.Count}");
            Console.WriteLine("==================================================");
            Console.WriteLine("扫描开始，请稍候...");
            
            try
            {   
                if (totalIPs == 0)
                {   
                    Console.WriteLine("错误: 没有有效的IP地址。");
                    return;
                }
                
                // 优化网络设置
                OptimizeNetworkSettings();
                
                // 初始化信号量和取消令牌
                cancellationTokenSource = new CancellationTokenSource();
                SemaphoreSlim semaphore = new SemaphoreSlim(threadCount);
                
                // 启动进度显示线程
                Task progressTask = Task.Run(() => ShowProgress());
                
                Stopwatch stopwatch = Stopwatch.StartNew();
                
                // 启动扫描任务
                List<Task> scanTasks = new List<Task>();
                for (int i = 0; i < threadCount; i++)
                {   
                    scanTasks.Add(ScanTask(semaphore, cancellationTokenSource.Token));
                }
                
                // 等待所有扫描任务完成
                Task.WaitAll(scanTasks.ToArray(), cancellationTokenSource.Token);
                
                // 取消进度显示线程
                cancellationTokenSource.Cancel();
                progressTask.Wait(TimeSpan.FromSeconds(1));
                
                stopwatch.Stop();
                
                // 导出结果（如果需要）
                if (saveResults)
                {   
                    ExportResults(outputFilePath);
                }
                
                // 显示扫描完成信息
                lock (consoleLock)
                {   
                    Console.WriteLine();
                    Console.WriteLine("==================================================");
                    Console.WriteLine("扫描完成！");
                    Console.WriteLine($"扫描IP总数: {totalIPs}");
                    Console.WriteLine($"扫描端口数: {scanPorts.Count}");
                    Console.WriteLine($"总扫描任务: {totalIPs * scanPorts.Count}");
                    Console.WriteLine($"发现开放端口: {openPortsCount}");
                    Console.WriteLine($"扫描耗时: {stopwatch.Elapsed.TotalSeconds:F2} 秒");
                    Console.WriteLine($"平均速度: {totalIPs * scanPorts.Count / stopwatch.Elapsed.TotalSeconds:F0} 端口/秒");
                    if (saveResults)
                    {   
                        Console.WriteLine($"结果已保存至: {outputFilePath}");
                    }
                    Console.WriteLine("==================================================");
                }
            }
            catch (Exception ex)
            {   
                Console.WriteLine($"扫描过程中发生错误: {ex.Message}");
                Console.WriteLine(ex.StackTrace);
            }
            finally
            {   
                // 清理资源
                if (cancellationTokenSource != null)
                {
                    cancellationTokenSource.Dispose();
                }
                
                // 清理Socket池
                while (socketPool.TryTake(out Socket socket))
                {
                    try { if (socket != null) socket.Dispose(); }
                    catch { }
                }
                
                // 不再等待用户按键，直接退出进程
                Environment.Exit(0);
            }
        }
        
        /// <summary>
        /// 从文件加载IP地址列表
        /// </summary>
        private static void LoadIPsFromFile(string filePath)
        {
            try
            {
                // 检查文件大小，限制为100MB，避免内存溢出
                FileInfo fileInfo = new FileInfo(filePath);
                
                if (fileInfo.Length > 100 * 1024 * 1024) // 100MB
                {
                    throw new Exception("文件过大，请使用不超过100MB的文件");
                }
                
                // 逐行读取文件，而不是一次性全部加载到内存
                using (StreamReader reader = new StreamReader(filePath, Encoding.UTF8))
                {
                    string line;
                    int lineCount = 0;
                    const int MAX_LINES = 1000000; // 限制最大行数为100万行
                    
                    while ((line = reader.ReadLine()) != null)
                    {
                        lineCount++;
                        
                        // 限制处理的行数，避免缓冲区溢出
                        if (lineCount > MAX_LINES)
                        {
                            throw new Exception("文件行数过多，请使用不超过100万行的文件");
                        }
                        
                        string trimmedLine = line.Trim();
                        if (string.IsNullOrEmpty(trimmedLine) || trimmedLine.StartsWith("#"))
                        {
                            continue;
                        }
                        
                        // 限制处理的IP总数，避免内存溢出
                        if (totalIPs > int.MaxValue - 10000)
                        {
                            throw new Exception("IP数量超过限制，请减少IP数量");
                        }
                        
                        if (IsChunzhenIPFormat(trimmedLine))
                        {   // 纯真IP库格式
                            ProcessChunzhenIPFormat(trimmedLine);
                        }                        else if (trimmedLine.Contains("/"))
                        {   // CIDR格式
                            ProcessCIDRFormat(trimmedLine);
                        }                        else if (trimmedLine.Contains("-"))
                        {   // IP范围格式（-分隔）
                            ProcessIPRangeFormat(trimmedLine);
                        }                        else if (trimmedLine.Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries).Length >= 2)
                        {   // IP范围格式（空格分隔）
                            string[] parts = trimmedLine.Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
                            if (parts.Length >= 2 && IPAddress.TryParse(parts[0], out _) && IPAddress.TryParse(parts[1], out _))
                            {
                                AddIPRange(parts[0], parts[1]);
                            }
                        }                        else
                        {   // 单个IP格式
                            // 验证IP地址格式
                            if (IPAddress.TryParse(trimmedLine, out _))
                            {
                                ipQueue.Enqueue(trimmedLine);
                                Interlocked.Increment(ref totalIPs);
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                throw new Exception($"加载IP文件时出错: {ex.Message}");
            }
        }
        
        /// <summary>
        /// 检查是否为纯真IP库格式
        /// </summary>
        private static bool IsChunzhenIPFormat(string line)
        {
            try
            {
                // 尝试用空格或制表符分割行，检查前两个部分是否为有效的IP地址
                string[] parts = line.Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
                if (parts.Length >= 2)
                {
                    return IPAddress.TryParse(parts[0], out _) && IPAddress.TryParse(parts[1], out _);
                }
                return false;
            }
            catch
            {
                return false;
            }
        }
        
        /// <summary>
        /// 处理纯真IP库格式的IP地址范围
        /// </summary>
        private static void ProcessChunzhenIPFormat(string line)
        {
            try
            {
                // 用空格或制表符分割行
                string[] parts = line.Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
                if (parts.Length >= 2)
                {
                    string startIP = parts[0];
                    string endIP = parts[1];
                    
                    // 使用现有的IP范围处理方法
                    ProcessIPRangeFormat($"{startIP}-{endIP}");
                }
            }
            catch { /* 忽略无效的纯真IP库格式 */ }
        }
        
        /// <summary>
        /// 处理CIDR格式的IP地址
        /// </summary>
        private static void ProcessCIDRFormat(string cidr)
        {   
            try
            {   
                string[] parts = cidr.Split('/');
                if (parts.Length != 2) return;
                
                // 验证前缀长度是否有效
                if (!int.TryParse(parts[1], out int prefixLength) || prefixLength < 0 || prefixLength > 32)
                    return;
                
                IPAddress ipAddress = IPAddress.Parse(parts[0]);
                
                // 计算IP范围大小，限制最大范围为65536个IP
                uint ipCount = (prefixLength < 32) ? (1U << (32 - prefixLength)) : 1U;
                if (ipCount > 65536) // 限制最大范围为65536个IP
                    return;
                
                // 简单实现CIDR转IP范围
                byte[] addressBytes = ipAddress.GetAddressBytes();
                uint address = (uint)IPAddress.NetworkToHostOrder((int)BitConverter.ToUInt32(addressBytes, 0));
                uint mask = 0xFFFFFFFF << (32 - prefixLength);
                uint network = address & mask;
                uint broadcast = network | ~mask;
                
                // 限制处理的IP数量，避免缓冲区溢出
                for (uint i = network + 1; i < broadcast && totalIPs < int.MaxValue - 1000; i++)
                {   
                    byte[] bytes = BitConverter.GetBytes(IPAddress.HostToNetworkOrder((int)i));
                    ipQueue.Enqueue(new IPAddress(bytes).ToString());
                    Interlocked.Increment(ref totalIPs);
                }
            }
            catch { /* 忽略无效的CIDR格式 */ }
        }
        
        /// <summary>
        /// 处理IP范围格式
        /// </summary>
        private static void ProcessIPRangeFormat(string range)
        {   
            try
            {   
                string[] parts = range.Split('-');
                if (parts.Length != 2) return;
                
                IPAddress startIP = IPAddress.Parse(parts[0].Trim());
                IPAddress endIP = IPAddress.Parse(parts[1].Trim());
                
                // 修复null值警告，确保获取的字节数组不为null
                byte[] startBytes = startIP.GetAddressBytes();
                byte[] endBytes = endIP.GetAddressBytes();
                
                // 确保BitConverter不会返回null
                uint start = (uint)IPAddress.NetworkToHostOrder((int)(BitConverter.ToUInt32(startBytes, 0)));
                uint end = (uint)IPAddress.NetworkToHostOrder((int)(BitConverter.ToUInt32(endBytes, 0)));
                
                // 检查起始IP是否小于等于结束IP，避免无限循环
                if (start > end)
                    return;
                
                // 计算IP范围大小，限制最大范围为65536个IP
                uint ipCount = end - start + 1;
                if (ipCount > 65536) // 限制最大范围为65536个IP
                    return;
                
                // 限制处理的IP数量，避免缓冲区溢出
                for (uint i = start; i <= end && totalIPs < int.MaxValue - 1000; i++)
                {   
                    byte[] bytes = BitConverter.GetBytes(IPAddress.HostToNetworkOrder((int)i));
                    // 确保IPAddress不会接收null
                    if (bytes != null)
                    {
                        IPAddress ipAddress = new IPAddress(bytes);
                        ipQueue.Enqueue(ipAddress.ToString());
                        Interlocked.Increment(ref totalIPs);
                    }
                }
            }
            catch { /* 忽略无效的IP范围格式 */ }
        }
    }
}